const CORP_ID = "ding40e8d2fad3d041ce35c2f4657eb6378f"
const waiqinReason = '居家办公' //外勤打卡原因
const PASSWORD = '000000'
const PACKAGE_ID_QQ = "com.tencent.mobileqq"                // QQ
const PACKAGE_ID_DD = "com.alibaba.android.rimet"           // 钉钉
const PACKAGE_ID_TASKER = "net.dinglisch.android.taskerm"   // Tasker
const PACKAGE_ID_MAIL_163 = "com.netease.mail"              // 网易邮箱大师
const PACKAGE_ID_MAIL_ANDROID = "com.android.email"         // 系统内置邮箱
const PACKAGE_ID_PUSHDEER = "com.pushdeer.os"               // Push Deer
const PACKAGE_ID_CALENDAR = "com.android.calendar"               // 系统内置日历
const LOWER_BOUND = 1 * 60 * 1000 // 最小等待时间：1min
const UPPER_BOUND = 4 * 60 * 1000 // 最大等待时间：4min
// PackageId白名单
const PACKAGE_ID_WHITE_LIST = [PACKAGE_ID_QQ,PACKAGE_ID_DD,PACKAGE_ID_MAIL_163,PACKAGE_ID_TASKER,PACKAGE_ID_PUSHDEER,PACKAGE_ID_CALENDAR]
// 周时间
const WEEK_DAY = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",]
var currentDate = new Date()
// 是否暂停定时打卡
var suspend = false
// 是否过滤通知
const NOTIFICATIONS_FILTER = true
// 本次打开打卡前是否需要等待
var needWaiting = true
// 监听音量+键, 开启后无法通过音量+键调整音量, 按下音量+键：结束所有子线程
const OBSERVE_VOLUME_KEY = true
// runOnce模式(仅运行一次模式)标志
var runOnceFlag = false
// 锁屏意图, 配合 Tasker 完成锁屏动作
const ACTION_LOCK_SCREEN = "autojs.intent.action.LOCK_SCREEN"

// 检查无障碍权限
auto.waitFor("normal")

//拦截音量按键操作
events.setKeyInterceptionEnabled("volume_up", OBSERVE_VOLUME_KEY)
//监听音量按键操作
if (OBSERVE_VOLUME_KEY) {
    events.observeKey()
};

// 监听本机通知
events.observeNotification()
events.on("notification", function (n) {
    notificationHandler(n)
});

// 监听音量+键
events.onKeyDown("volume_up", function (event) {
    threads.shutDownAll()
    device.setBrightnessMode(1)
    device.cancelKeepingAwake()
    toast("已中断所有子线程!")

    // 可以在此调试各个方法
    // doClock()
    // sendQQMsg("测试文本")
    // sendEmail("测试主题", "测试文本", null)
    // sendServerChan(测试主题, 测试文本)
    // sendPushDeer(测试主题, 测试文本)
});

// 监听run_once模式事件
events.on("run_once",function(e){
    console.log('received run_once event')
    runOnceFlag = true
    doClock()
})

// =================== ↑↑↑ 主线程：监听通知 ↑↑↑ =====================



/**
 * @description 处理通知
 */
function notificationHandler(n) {
    console.log(n)
    var packageId = n.getPackageName()  // 获取通知包名
    var abstract = n.tickerText         // 获取通知摘要
    var text = n.getText()              // 获取通知文本
    var title = n.getTitle()            // 获取通知标题

    // 过滤 PackageId 白名单之外的应用所发出的通知
    if (!filterNotification(packageId, abstract, text)) {
        return;
    }

    // 监听摘要为 "定时打卡" 的通知, 不一定要从 Tasker 中发出通知, 日历、定时器等App均可实现
    if ((abstract == "定时打卡" || title == "定时打卡") && !suspend) {
        needWaiting = true
        threads.shutDownAll()
        threads.start(function () {
            doClock()
        })
        return;
    }

    switch (text) {

        case "打卡": // 监听文本为 "打卡" 的通知
            needWaiting = false
            threads.shutDownAll()
            threads.start(function () {
                doClock()
            })
            break;

        // case "查询": // 监听文本为 "查询" 的通知
        //     threads.shutDownAll()
        //     threads.start(function(){
        //         switch(DEFAULT_MESSAGE_DELIVER) {
        //             case PUSH_METHOD.QQ:
        //                 sendQQMsg(getStorageData("dingding", "clockResult"))
        //                break;
        //             case PUSH_METHOD.Email:
        //                 sendEmail("考勤结果", getStorageData("dingding", "clockResult"), null)
        //                break;
        //             case PUSH_METHOD.ServerChan:
        //                 sendServerChan("考勤结果", getStorageData("dingding", "clockResult"))
        //                break;
        //             case PUSH_METHOD.PushDeer:
        //                 sendPushDeer("考勤结果", getStorageData("dingding", "clockResult"))
        //                break;
        //         }
        //     })
        //     break;

        // case "暂停": // 监听文本为 "暂停" 的通知
        //     suspend = true
        //     console.warn("暂停定时打卡")
        //     threads.shutDownAll()
        //     threads.start(function(){
        //         switch(DEFAULT_MESSAGE_DELIVER) {
        //             case PUSH_METHOD.QQ:
        //                 sendQQMsg("修改成功, 已暂停定时打卡功能")
        //                break;
        //             case PUSH_METHOD.Email:
        //                 sendEmail("修改成功", "已暂停定时打卡功能", null)
        //                break;
        //             case PUSH_METHOD.ServerChan:
        //                 sendServerChan("修改成功", "已暂停定时打卡功能")
        //                break;
        //             case PUSH_METHOD.PushDeer:
        //                 sendPushDeer("修改成功", "已暂停定时打卡功能")
        //                break;
        //         }
        //     })
        //     break;

        // case "恢复": // 监听文本为 "恢复" 的通知
        //     suspend = false
        //     console.warn("恢复定时打卡")
        //     threads.shutDownAll()
        //     threads.start(function(){
        //         switch(DEFAULT_MESSAGE_DELIVER) {
        //             case PUSH_METHOD.QQ:
        //                 sendQQMsg("修改成功, 已恢复定时打卡功能")
        //                break;
        //             case PUSH_METHOD.Email:
        //                 sendEmail("修改成功", "已恢复定时打卡功能", null)
        //                break;
        //             case PUSH_METHOD.ServerChan:
        //                 sendServerChan("修改成功", "已恢复定时打卡功能")
        //                break;
        //             case PUSH_METHOD.PushDeer:
        //                 sendPushDeer("修改成功", "已恢复定时打卡功能")
        //                break;
        //         }
        //     })
        //     break;

        case "日志": // 监听文本为 "日志" 的通知
            threads.shutDownAll()
            threads.start(function () {
                sendEmail("获取日志", globalLogFilePath, globalLogFilePath)
            })
            break;

        default:
            break;
    }

    if (text == null)
        return;

    // 监听钉钉返回的考勤结果
    // if (packageId == PACKAGE_ID_DD && text.indexOf("考勤打卡") >= 0) { 
    //     setStorageData("dingding", "clockResult", text)
    //     threads.shutDownAll()
    //     threads.start(function() {
    //         switch(DEFAULT_MESSAGE_DELIVER) {
    //             case PUSH_METHOD.QQ:
    //                 sendQQMsg(text)
    //                break;
    //             case PUSH_METHOD.Email:
    //                 sendEmail("考勤结果", text, cameraFilePath)
    //                break;
    //             case PUSH_METHOD.ServerChan:
    //                 sendServerChan("考勤结果", text)
    //                break;
    //             case PUSH_METHOD.PushDeer:
    //                 sendPushDeer("考勤结果", text)
    //                break;
    //        }
    //     })
    //     return;
    // }
}

// 通知过滤器
function filterNotification(bundleId, abstract, text) {
    var check = PACKAGE_ID_WHITE_LIST.some(function(item) {return bundleId == item}) 
    if (!NOTIFICATIONS_FILTER || check) {
        console.verbose(bundleId)
        console.verbose(abstract)
        console.verbose(text)
        console.verbose("---------------------------")
        return true
    }
    else {
        console.log('filted notification:',bundleId,' ',abstract,' ',text)
        return false 
    }
}



/**
 * @description 发送邮件流程
 * @param {string} title 邮件主题
 * @param {string} message 邮件正文
 * @param {string} attachFilePath 要发送的附件路径
 */
function sendEmail(title, message, attachFilePath) {

    console.log("开始发送邮件流程!")

    brightScreen()      // 唤醒屏幕
    unlockScreen()      // 解锁屏幕

    if (attachFilePath != null && files.exists(attachFilePath)) {
        console.info(attachFilePath)
        app.sendEmail({
            email: [EMAILL_ADDRESS], subject: title, text: message, attachment: attachFilePath
        })
    }
    else {
        console.error(attachFilePath)
        app.sendEmail({
            email: [EMAILL_ADDRESS], subject: title, text: message
        })
    }

    console.log("选择邮件应用")
    waitForActivity("com.android.internal.app.ChooserActivity") // 等待选择应用界面弹窗出现, 如果设置了默认应用就注释掉

    var emailAppName = app.getAppName(PACKAGE_ID_MAIL_163)
    if (null != emailAppName) {
        if (null != textMatches(emailAppName).findOne(1000)) {
            btn_email = textMatches(emailAppName).findOnce().parent()
            btn_email.click()
        }
    }
    else {
        console.error("不存在应用: " + PACKAGE_ID_MAIL_163)
        lockScreen()
        return;
    }

    // 网易邮箱大师
    var versoin = getPackageVersion(PACKAGE_ID_MAIL_163)
    console.log("应用版本: " + versoin)
    var sp = versoin.split(".")
    if (sp[0] == 6) {
        // 网易邮箱大师 6
        waitForActivity("com.netease.mobimail.activity.MailComposeActivity")
        id("send").findOne().click()
    }
    else {
        // 网易邮箱大师 7
        waitForActivity("com.netease.mobimail.module.mailcompose.MailComposeActivity")
        var input_address = id("input").findOne()
        if (null == input_address.getText()) {
            input_address.setText(EMAILL_ADDRESS)
        }
        id("iv_arrow").findOne().click()
        sleep(1000)
        id("img_send_bg").findOne().click()
    }

    // 内置电子邮件
    // waitForActivity("com.kingsoft.mail.compose.ComposeActivity")
    // id("compose_send_btn").findOne().click()

    console.log("正在发送邮件...")

    home()
    sleep(2000)
    lockScreen()    // 关闭屏幕
}


/**
 * @description 发送QQ消息
 * @param {string} message 消息内容
 */
function sendQQMsg(message) {

    console.log("发送QQ消息")

    brightScreen()      // 唤醒屏幕
    unlockScreen()      // 解锁屏幕

    app.startActivity({
        action: "android.intent.action.VIEW",
        data: "mqq://im/chat?chat_type=wpa&version=1&src_type=web&uin=" + QQ,
        packageName: "com.tencent.mobileqq",
    });

    // waitForActivity("com.tencent.mobileqq.activity.SplashActivity")

    id("input").findOne().setText(message)
    id("fun_btn").findOne().click()

    home()
    sleep(1000)
    lockScreen()    // 关闭屏幕
}


/**
 * @description ServerChan推送
 * @param {string} title 标题
 * @param {string} message 消息
 */
function sendServerChan(title, message) {

    console.log("向 ServerChan 发起推送请求")

    url = "https://sctapi.ftqq.com/" + SERVER_CHAN + ".send";

    res = http.post(encodeURI(url), {
        "title": title,
        "desp": message
    });

    console.log(res)
    sleep(1000)
    lockScreen()    // 关闭屏幕
}


/**
 * @description PushDeer推送
 * @param {string} title 标题
 * @param {string} message 消息
 */
function sendPushDeer(title, message) {

    console.log("向 PushDeer 发起推送请求")

    url = "https://api2.pushdeer.com/message/push"

    res = http.post(encodeURI(url), {
        "pushkey": PUSH_DEER,
        "text": title,
        "desp": message,
        "type": "markdown",
    });

    console.log(res)
    sleep(1000)
    lockScreen()    // 关闭屏幕
}


/**
 * @description 打卡流程
 */
function doClock() {

    currentDate = new Date()
    console.log("本地时间: " + getCurrentDate() + " " + getCurrentTime())
    console.log("开始打卡流程!")
    //点亮屏幕
    brightScreen()
    //解锁屏幕
    unlockScreen()
    //home页
    home()
    //运行目标程序
    //app.launchApp('打卡')
    toast('test')

    sleep(3 * 1000)
    //随机等待
    holdOn()
    //进入考勤界面
    attendKaoqin()
    //考勤
    clockIn()
    //processWaiqin()
    //锁屏
    lockScreen()
}

/**
 * @description 唤醒设备
 */
function brightScreen() {

    console.log("唤醒设备")

    // device.setBrightnessMode(0) // 手动亮度模式
    // device.setBrightness(SCREEN_BRIGHTNESS)
    device.wakeUpIfNeeded() // 唤醒设备
    device.keepScreenOn()   // 保持亮屏
    sleep(1000) // 等待屏幕亮起

    if (!device.isScreenOn()) {
        console.warn("设备未唤醒, 重试")
        device.wakeUpIfNeeded()
        brightScreen()
    }
    else {
        console.info("设备已唤醒")
    }
    sleep(1000)
}


/**
 * @description 解锁屏幕
 */
function unlockScreen() {

    console.log("解锁屏幕")

    if (isDeviceLocked()) {

        gesture(
            320, // 滑动时间：毫秒
            [
                device.width * 0.5,    // 滑动起点 x 坐标：屏幕宽度的一半
                device.height * 0.9     // 滑动起点 y 坐标：距离屏幕底部 10% 的位置, 华为系统需要往上一些
            ],
            [
                device.width / 2,       // 滑动终点 x 坐标：屏幕宽度的一半
                device.height * 0.1     // 滑动终点 y 坐标：距离屏幕顶部 10% 的位置
            ]
        )

        sleep(1000) // 等待解锁动画完成
        home()
        sleep(1000) // 等待返回动画完成
        password_input(PASSWORD)
        sleep(1000) // 等待密码解锁动画完成
    }

    if (isDeviceLocked()) {
        console.error("上滑解锁失败, 请按脚本中的注释调整 gesture(time, [x1,y1], [x2,y2]) 方法的参数!")
        return;
    }
    console.info("屏幕已解锁")
}
// 输入密码
function password_input(password) {
    console.log('输入密码')
    for (var i = 0; i < password.length; i++) {
        var p = text(password[i].toString()).findOne().bounds();
        console.log(p)
        click(p.centerX(), p.centerY());
        sleep(100);
    }
}
//锁屏
function lockScreen() {
    //处在run_once模式时由外部脚本进行锁屏
    if (runOnceFlag) {return}

    console.log("关闭屏幕")

    // 锁屏方案1：Root
    // Power()

    // 锁屏方案2：No Root
    // press(Math.floor(device.width / 2), Math.floor(device.height * 0.973), 1000) // 小米的快捷手势：长按Home键锁屏

    // 万能锁屏方案：向Tasker发送广播, 触发系统锁屏动作。配置方法见 2021-03-09 更新日志
    //app.sendBroadcast({action: ACTION_LOCK_SCREEN});

    device.setBrightnessMode(1) // 自动亮度模式
    device.cancelKeepingAwake() // 取消设备常亮

    if (isDeviceLocked()) {
        console.info("屏幕已关闭")
    }
    else {
        //发送锁屏意图
        app.sendBroadcast({ action: ACTION_LOCK_SCREEN });
        //console.error("屏幕未关闭, 请尝试其他锁屏方案, 或等待屏幕自动关闭")
    }
}

function attendKaoqin() {

    // var url_scheme = "dingtalk://dingtalkclient/page/link?url=https://attend.dingtalk.com/attend/index.html"

    // if(CORP_ID != "") {
    //     url_scheme = url_scheme + "?corpId=" + CORP_ID
    // }

    // var a = app.intent({
    //     action: "VIEW",
    //     data: url_scheme,
    //     //flags: [Intent.FLAG_ACTIVITY_NEW_TASK]
    // });
    // app.startActivity(a);
    console.log("正在进入考勤界面...")
    className('android.widget.TextView').text('打卡').findOne().click()
    textContains("打卡").waitFor()
    console.info("已进入考勤界面")
    //等待考勤界面渲染
    sleep(3000)
}

function clockIn() {
    if (null != textMatches("上班打卡").clickable(true).findOne(1000)) {
        btn_clockin = textMatches("上班打卡").clickable(true).findOnce()
        btn_clockin.click()
        console.log("按下打卡按钮")
    }
    else {
        click(device.width / 2, device.height * 0.330)
        console.log("点击打卡按钮坐标")
    }
    sleep(5 * 1000)
    // threads.start(function () {
    //     engines.execScriptFile('./test.js')
    // })

    //click(device.width / 2, device.height * 0.590)
    console.log("点击打卡按钮坐标")
    console.info("已进入考勤界面")
}

function clockOut() {
    if (null != textMatches("下班打卡").clickable(true).findOne(1000)) {
        btn_clockout = textMatches("下班打卡").clickable(true).findOnce()
        btn_clockout.click()
        console.log("按下打卡按钮")
        sleep(1000)
    }
    else {
        click(device.width / 2, device.height * 0.450)
        console.log("点击打卡按钮坐标")
    }

    if (null != textContains("早退打卡").clickable(true).findOne(1000)) {
        className("android.widget.Button").text("早退打卡").clickable(true).findOnce().parent().click()
        console.warn("早退打卡")
    }

    home()
    sleep(1000)
}

function processWaiqin() {
    sleep(5 * 1000)
    console.log('判断是否为外勤')
    if (null != textContains("外勤打卡").clickable(true).findOne(2000)) {
        console.log('外勤打卡处理>>>>>')
        let textField = editable(true).findOne(2000)
        if (textField) {
            console.log('输入外勤打卡原因')
            textField.setText(waiqinReason)
            console.log('点击外勤打卡按钮')
            className("android.widget.Button").textContains("外勤打卡").findOne(2000).parent().click()
        } else {
            console.log('未找到外勤打卡输入框')
        }
    } else {
        console.log('非外勤打卡')
    }
}
// ===================== ↓↓↓ 功能函数 ↓↓↓ =======================


/**
 * @description 随机等待
 */
 function holdOn(){

    if (!needWaiting) {
        return;
    }

    var randomTime = random(LOWER_BOUND, UPPER_BOUND)
    toastLog(Math.floor(randomTime / 1000) + "秒后启动" +"weLink"+ "...")
    sleep(randomTime)
}

function dateDigitToString(num){
    return num < 10 ? '0' + num : num
}

function getCurrentTime(){
    var currentDate = new Date()
    var hours = dateDigitToString(currentDate.getHours())
    var minute = dateDigitToString(currentDate.getMinutes())
    var second = dateDigitToString(currentDate.getSeconds())
    var formattedTimeString = hours + ':' + minute + ':' + second
    return formattedTimeString
}

function getCurrentDate(){
    var currentDate = new Date()
    var year = dateDigitToString(currentDate.getFullYear())
    var month = dateDigitToString(currentDate.getMonth() + 1)
    var date = dateDigitToString(currentDate.getDate())
    var week = currentDate.getDay()
    var formattedDateString = year + '-' + month + '-' + date + '-' + WEEK_DAY[week]
    return formattedDateString
}

// 保存本地数据
function setStorageData(name, key, value) {
    const storage = storages.create(name)  // 创建storage对象
    storage.put(key, value)
}

// 读取本地数据
function getStorageData(name, key) {
    const storage = storages.create(name)
    if (storage.contains(key)) {
        return storage.get(key, "")
    }
    // 默认返回undefined
}

// 删除本地数据
function delStorageData(name, key) {
    const storage = storages.create(name)
    if (storage.contains(key)) {
        storage.remove(key)
    }
}



// 屏幕是否为锁定状态
function isDeviceLocked() {
    importClass(android.app.KeyguardManager)
    importClass(android.content.Context)
    var km = context.getSystemService(Context.KEYGUARD_SERVICE)
    return km.isKeyguardLocked()
}